From 3c4b9522561d154d83721c61a95e01d7bbe23c21 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 6 Dec 2016 14:42:46 +0100 Subject: [PATCH] vulkan: Make GskVulkanRenderer work We now create a Cairo renderer, render to an image surface and upload and retnder it with Vulkan. --- gsk/Makefile.am | 2 + gsk/gskvulkanimage.c | 295 ++++++++++++++++++++++++++++ gsk/gskvulkanimageprivate.h | 23 +++ gsk/gskvulkanpipeline.c | 35 +++- gsk/gskvulkanpipelineprivate.h | 2 + gsk/gskvulkanrenderer.c | 137 ++++++++++++- gsk/resources/vulkan/blit.frag.glsl | 4 +- gsk/resources/vulkan/blit.frag.spv | Bin 564 -> 632 bytes 8 files changed, 493 insertions(+), 5 deletions(-) create mode 100644 gsk/gskvulkanimage.c create mode 100644 gsk/gskvulkanimageprivate.h diff --git a/gsk/Makefile.am b/gsk/Makefile.am index 84ae987602..a29ebc55f8 100644 --- a/gsk/Makefile.am +++ b/gsk/Makefile.am @@ -25,12 +25,14 @@ noinst_LTLIBRARIES = if HAVE_VULKAN gsk_private_vulan_source_h = \ gskvulkanbufferprivate.h \ + gskvulkanimageprivate.h \ gskvulkanmemoryprivate.h \ gskvulkanpipelineprivate.h \ gskvulkanrendererprivate.h \ gskvulkanshaderprivate.h gsk_private_vulkan_source_c = \ gskvulkanbuffer.c \ + gskvulkanimage.c \ gskvulkanmemory.c \ gskvulkanpipeline.c \ gskvulkanrenderer.c \ diff --git a/gsk/gskvulkanimage.c b/gsk/gskvulkanimage.c new file mode 100644 index 0000000000..c8777f7063 --- /dev/null +++ b/gsk/gskvulkanimage.c @@ -0,0 +1,295 @@ +#include "config.h" + +#include "gskvulkanimageprivate.h" +#include "gskvulkanmemoryprivate.h" +#include "gskvulkanpipelineprivate.h" + +#include + +struct _GskVulkanImage +{ + GdkVulkanContext *vulkan; + + VkImage vk_image; + VkImageView vk_image_view; + + GskVulkanMemory *memory; +}; + +static GskVulkanImage * +gsk_vulkan_image_new (GdkVulkanContext *context, + gsize width, + gsize height, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkMemoryPropertyFlags memory) +{ + VkMemoryRequirements requirements; + GskVulkanImage *self; + + self = g_slice_new0 (GskVulkanImage); + + self->vulkan = g_object_ref (context); + + GSK_VK_CHECK (vkCreateImage, gdk_vulkan_context_get_device (context), + &(VkImageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .flags = 0, + .imageType = VK_IMAGE_TYPE_2D, + .format = VK_FORMAT_B8G8R8A8_SRGB, + .extent = { width, height, 1 }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = tiling, + .usage = usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED + }, + NULL, + &self->vk_image); + + vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (context), + self->vk_image, + &requirements); + + self->memory = gsk_vulkan_memory_new (context, + requirements.memoryTypeBits, + memory, + requirements.size); + + GSK_VK_CHECK (vkBindImageMemory, gdk_vulkan_context_get_device (context), + self->vk_image, + gsk_vulkan_memory_get_device_memory (self->memory), + 0); + return self; +} + +static GskVulkanImage * +gsk_vulkan_image_new_staging (GdkVulkanContext *context, + guchar *data, + gsize width, + gsize height, + gsize stride) +{ + VkMemoryRequirements requirements; + GskVulkanImage *self; + guchar *mem; + gsize mem_stride; + + self = gsk_vulkan_image_new (context, + width, + height, + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + mem_stride = width * 4; + vkGetImageMemoryRequirements (gdk_vulkan_context_get_device (context), + self->vk_image, + &requirements); + if (mem_stride % requirements.alignment != 0) + mem_stride = (mem_stride / requirements.alignment + 1) * requirements.alignment; + + mem = gsk_vulkan_memory_map (self->memory); + + if (stride == width * 4 && stride == mem_stride) + { + memcpy (mem, data, width * height * 4); + } + else + { + for (gsize i = 0; i < height; i++) + { + memcpy (mem + i * mem_stride, data + i * stride, width * 4); + } + } + + gsk_vulkan_memory_unmap (self->memory); + + return self; +} + +static void +gsk_vulkan_image_ensure_view (GskVulkanImage *self) +{ + GSK_VK_CHECK (vkCreateImageView, gdk_vulkan_context_get_device (self->vulkan), + &(VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = self->vk_image, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = VK_FORMAT_B8G8R8A8_SRGB, + .components = { + .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A, + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }, + NULL, + &self->vk_image_view); +} + +GskVulkanImage * +gsk_vulkan_image_new_from_data (GdkVulkanContext *context, + VkCommandBuffer command_buffer, + guchar *data, + gsize width, + gsize height, + gsize stride) +{ + GskVulkanImage *self, *staging; + + staging = gsk_vulkan_image_new_staging (context, data, width, height, stride); + + self = gsk_vulkan_image_new (context, + width, + height, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + vkCmdPipelineBarrier (command_buffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + 0, + 0, NULL, + 0, NULL, + 2, (VkImageMemoryBarrier[2]) { + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = staging->vk_image, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1 + } + }, + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_HOST_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = self->vk_image, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1 + } + } + }); + + vkCmdCopyImage (command_buffer, + staging->vk_image, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + self->vk_image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, + &(VkImageCopy) { + .srcSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1 + }, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1 + }, + .dstOffset = { 0, 0, 0 }, + .extent = { + .width = width, + .height = height, + .depth = 1 + } + }); + + vkCmdPipelineBarrier (command_buffer, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + 0, + 0, NULL, + 0, NULL, + 1, (VkImageMemoryBarrier[1]) { + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = self->vk_image, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1 + } + } + }); + + gsk_vulkan_image_free (staging); + + gsk_vulkan_image_ensure_view (self); + + return self; +} + +void +gsk_vulkan_image_free (GskVulkanImage *self) +{ + if (self->vk_image_view != VK_NULL_HANDLE) + { + vkDestroyImageView (gdk_vulkan_context_get_device (self->vulkan), + self->vk_image_view, + NULL); + } + + gsk_vulkan_memory_free (self->memory); + + vkDestroyImage (gdk_vulkan_context_get_device (self->vulkan), + self->vk_image, + NULL); + + g_object_unref (self->vulkan); + + g_slice_free (GskVulkanImage, self); +} + +VkImage +gsk_vulkan_image_get_image (GskVulkanImage *self) +{ + return self->vk_image; +} + +VkImageView +gsk_vulkan_image_get_image_view (GskVulkanImage *self) +{ + return self->vk_image_view; +} + diff --git a/gsk/gskvulkanimageprivate.h b/gsk/gskvulkanimageprivate.h new file mode 100644 index 0000000000..57686eac04 --- /dev/null +++ b/gsk/gskvulkanimageprivate.h @@ -0,0 +1,23 @@ +#ifndef __GSK_VULKAN_IMAGE_PRIVATE_H__ +#define __GSK_VULKAN_IMAGE_PRIVATE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GskVulkanImage GskVulkanImage; + +GskVulkanImage * gsk_vulkan_image_new_from_data (GdkVulkanContext *context, + VkCommandBuffer command_buffer, + guchar *data, + gsize width, + gsize height, + gsize stride); +void gsk_vulkan_image_free (GskVulkanImage *image); + +VkImage gsk_vulkan_image_get_image (GskVulkanImage *self); +VkImageView gsk_vulkan_image_get_image_view (GskVulkanImage *self); + +G_END_DECLS + +#endif /* __GSK_VULKAN_IMAGE_PRIVATE_H__ */ diff --git a/gsk/gskvulkanpipeline.c b/gsk/gskvulkanpipeline.c index 93f0cf71d3..012eb8f949 100644 --- a/gsk/gskvulkanpipeline.c +++ b/gsk/gskvulkanpipeline.c @@ -12,6 +12,7 @@ struct _GskVulkanPipeline VkPipeline pipeline; VkPipelineLayout pipeline_layout; + VkDescriptorSetLayout descriptor_set_layout; GskVulkanShader *vertex_shader; GskVulkanShader *fragment_shader; @@ -36,6 +37,10 @@ gsk_vulkan_pipeline_finalize (GObject *gobject) self->pipeline_layout, NULL); + vkDestroyDescriptorSetLayout (device, + self->descriptor_set_layout, + NULL); + g_clear_object (&self->vulkan); G_OBJECT_CLASS (gsk_vulkan_pipeline_parent_class)->finalize (gobject); @@ -68,10 +73,27 @@ gsk_vulkan_pipeline_new (GdkVulkanContext *context, self->vulkan = g_object_ref (context); + GSK_VK_CHECK (vkCreateDescriptorSetLayout, device, + &(VkDescriptorSetLayoutCreateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = 1, + .pBindings = (VkDescriptorSetLayoutBinding[1]) { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT + } + } + }, + NULL, + &self->descriptor_set_layout); + GSK_VK_CHECK (vkCreatePipelineLayout, device, &(VkPipelineLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .setLayoutCount = 0, + .setLayoutCount = 1, + .pSetLayouts = &self->descriptor_set_layout }, NULL, &self->pipeline_layout); @@ -179,4 +201,15 @@ gsk_vulkan_pipeline_get_pipeline (GskVulkanPipeline *self) return self->pipeline; } +VkPipelineLayout +gsk_vulkan_pipeline_get_pipeline_layout (GskVulkanPipeline *self) +{ + return self->pipeline_layout; +} + +VkDescriptorSetLayout +gsk_vulkan_pipeline_get_descriptor_set_layout (GskVulkanPipeline *self) +{ + return self->descriptor_set_layout; +} diff --git a/gsk/gskvulkanpipelineprivate.h b/gsk/gskvulkanpipelineprivate.h index b4e9e285ba..8395a2dab4 100644 --- a/gsk/gskvulkanpipelineprivate.h +++ b/gsk/gskvulkanpipelineprivate.h @@ -28,6 +28,8 @@ GskVulkanPipeline * gsk_vulkan_pipeline_new (GdkVulk VkRenderPass render_pass); VkPipeline gsk_vulkan_pipeline_get_pipeline (GskVulkanPipeline *self); +VkPipelineLayout gsk_vulkan_pipeline_get_pipeline_layout (GskVulkanPipeline *self); +VkDescriptorSetLayout gsk_vulkan_pipeline_get_descriptor_set_layout (GskVulkanPipeline *self); G_END_DECLS diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c index d8464497f2..060459b102 100644 --- a/gsk/gskvulkanrenderer.c +++ b/gsk/gskvulkanrenderer.c @@ -9,6 +9,7 @@ #include "gskrendernodeprivate.h" #include "gsktextureprivate.h" #include "gskvulkanbufferprivate.h" +#include "gskvulkanimageprivate.h" #include "gskvulkanpipelineprivate.h" typedef struct _GskVulkanTarget GskVulkanTarget; @@ -33,8 +34,13 @@ struct _GskVulkanRenderer VkCommandPool command_pool; VkFence command_pool_fence; + VkDescriptorPool descriptor_pool; + VkDescriptorSet descriptor_set; + GskVulkanPipeline *pipeline; + VkSampler sampler; + #ifdef G_ENABLE_DEBUG ProfileTimers profile_timers; #endif @@ -228,9 +234,48 @@ gsk_vulkan_renderer_realize (GskRenderer *renderer, NULL, &self->command_pool_fence); - self->pipeline = gsk_vulkan_pipeline_new (self->vulkan, self->render_pass); + GSK_VK_CHECK (vkCreateDescriptorPool, device, + &(VkDescriptorPoolCreateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .maxSets = 1, + .poolSizeCount = 1, + .pPoolSizes = (VkDescriptorPoolSize[1]) { + { + .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1 + } + } + }, + NULL, + &self->descriptor_pool); + + GSK_VK_CHECK (vkAllocateDescriptorSets, device, + &(VkDescriptorSetAllocateInfo) { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .descriptorPool = self->descriptor_pool, + .descriptorSetCount = 1, + .pSetLayouts = (VkDescriptorSetLayout[1]) { + gsk_vulkan_pipeline_get_descriptor_set_layout (self->pipeline) + } + }, + &self->descriptor_set); + + GSK_VK_CHECK (vkCreateSampler, device, + &(VkSamplerCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_LINEAR, + .minFilter = VK_FILTER_LINEAR, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + .unnormalizedCoordinates = VK_FALSE + }, + NULL, + &self->sampler); + g_signal_connect (self->vulkan, "images-updated", G_CALLBACK (gsk_vulkan_renderer_update_images_cb), @@ -253,6 +298,19 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer) gsk_vulkan_renderer_update_images_cb, self); + vkDestroySampler (device, + self->sampler, + NULL); + self->sampler = VK_NULL_HANDLE; + + vkDestroyDescriptorPool (device, + self->descriptor_pool, + NULL); + self->descriptor_pool = VK_NULL_HANDLE; + self->descriptor_set = VK_NULL_HANDLE; + + g_clear_object (&self->pipeline); + vkDestroyFence (device, self->command_pool_fence, NULL); @@ -271,6 +329,46 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer) g_clear_object (&self->vulkan); } +static GskVulkanImage * +gsk_vulkan_renderer_prepare_render (GskVulkanRenderer *self, + VkCommandBuffer command_buffer, + GskRenderNode *root) +{ + GdkWindow *window; + GskRenderer *fallback; + GskVulkanImage *image; + cairo_surface_t *surface; + cairo_t *cr; + + window = gsk_renderer_get_window (GSK_RENDERER (self)); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + gdk_window_get_width (window), + gdk_window_get_height (window)); + cr = cairo_create (surface); + fallback = gsk_renderer_create_fallback (GSK_RENDERER (self), + &GRAPHENE_RECT_INIT( + 0, 0, + gdk_window_get_width (window), + gdk_window_get_height (window) + ), + cr); + + gsk_renderer_render (fallback, root, NULL); + g_object_unref (fallback); + + cairo_destroy (cr); + + image = gsk_vulkan_image_new_from_data (self->vulkan, + command_buffer, + cairo_image_surface_get_data (surface), + cairo_image_surface_get_width (surface), + cairo_image_surface_get_height (surface), + cairo_image_surface_get_stride (surface)); + cairo_surface_destroy (surface); + + return image; +} + static void gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self, VkCommandBuffer command_buffer) @@ -297,6 +395,15 @@ gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self, VK_PIPELINE_BIND_POINT_GRAPHICS, gsk_vulkan_pipeline_get_pipeline (self->pipeline)); + vkCmdBindDescriptorSets (command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + gsk_vulkan_pipeline_get_pipeline_layout (self->pipeline), + 0, + 1, + &self->descriptor_set, + 0, + NULL); + vkCmdBindVertexBuffers (command_buffer, 0, 1, @@ -315,7 +422,7 @@ gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self, static void gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self, VkCommandBuffer command_buffer, - GskRenderNode *root) + GskVulkanImage *image) { GdkRectangle extents; GdkWindow *window; @@ -324,6 +431,25 @@ gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self, cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (GSK_RENDERER (self))), &extents); + vkUpdateDescriptorSets (gdk_vulkan_context_get_device (self->vulkan), + 1, + (VkWriteDescriptorSet[1]) { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = self->descriptor_set, + .dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &(VkDescriptorImageInfo) { + .sampler = self->sampler, + .imageView = gsk_vulkan_image_get_image_view (image), + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + } + } + }, + 0, NULL); + vkCmdBeginRenderPass (command_buffer, &(VkRenderPassBeginInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, @@ -371,6 +497,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, { GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); VkCommandBuffer command_buffer; + GskVulkanImage *image; #ifdef G_ENABLE_DEBUG GskProfiler *profiler; gint64 cpu_time; @@ -396,7 +523,9 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, .flags = 0 }); - gsk_vulkan_renderer_do_render_pass (self, command_buffer, root); + image = gsk_vulkan_renderer_prepare_render (self, command_buffer, root); + + gsk_vulkan_renderer_do_render_pass (self, command_buffer, image); GSK_VK_CHECK (vkEndCommandBuffer, command_buffer); @@ -429,6 +558,8 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, self->command_pool, 0); + gsk_vulkan_image_free (image); + #ifdef G_ENABLE_DEBUG cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time); gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time); diff --git a/gsk/resources/vulkan/blit.frag.glsl b/gsk/resources/vulkan/blit.frag.glsl index acc86807dd..5d7c81856a 100644 --- a/gsk/resources/vulkan/blit.frag.glsl +++ b/gsk/resources/vulkan/blit.frag.glsl @@ -2,9 +2,11 @@ layout(location = 0) in vec2 inTexCoord; +layout(set = 0, binding = 0) uniform sampler2D inTexture; + layout(location = 0) out vec4 color; void main() { - color = vec4 (inTexCoord, 0.0, 1.0); + color = texture (inTexture, inTexCoord); } diff --git a/gsk/resources/vulkan/blit.frag.spv b/gsk/resources/vulkan/blit.frag.spv index 05fd46999761579f2fccfac3df43a2b6d53c7a1a..9dcff6d120b133e6c797fcb6a16399231a26177b 100644 GIT binary patch delta 292 zcmXv}I|{;35S(WcHEPuOLBu98mk>lN!NOJ$u})!QAqsYu)*%@w`m z>@d9dazAe1RFWEC*mVrDU}M5;{}=`Uj;C#UyIjvHcaI%r?9TkXs28Sw)^sS@e{ delta 223 zcmeytvW110nMs+Qfq@YSIT(Z|@_IA!OpI&?5?_@Wc_v#jMhA#9urP2jFfgzIF%u9g z0QuZNnh}UW;?__;4^&JW$OozA17Z+>@%h2L2K&h(ObRI=jl4h%(iF(R3f3S16$4Um qF+r#p$g%(ib|7S65CUS5T96#b5|F`m49pCiKpG_X7w9w#AO-*!84fuB -- 2.30.2